const {Util} = require('dob_common');
const PoolError = require('./Error');

class Pool {
  constructor(type) {
    this.$pool = [];
    this.$type = type;
  }

  push(instance, timeWait = 0) {
    if(instance === void 0) {
      return;
    }

    if(Number.isInteger(timeWait) === false || timeWait < 0) {
      throw new PoolError(PoolError.PUSH_TIMEWAIT_INVALID);
    }

    if(!(instance instanceof this.$type)) {
      throw new PoolError(PoolError.INSTANCE_TYPE_ERROR);
    }

    setTimeout(() => {
      this.$pool.push(instance);
    }, timeWait, this);
  }

  async pop(timeWait = 10000) {
    if(Number.isInteger(timeWait) === false || timeWait < 0) {
      throw new PoolError(PoolError.POP_TIMEWAIT_INVALID);
    }

    let startTimestamp = (new Date()).getTime();

    while(true) {
      if(this.$pool.length > 0) {
        return this.$pool.pop();
      }
      else {
        await Util.sleep(100);
      }

      let endTimestamp = (new Date()).getTime();

      if(endTimestamp - startTimestamp > timeWait) {
        break;
      }
    }

    throw new PoolError(PoolError.POP_TIMEOUT);
  }
}

module.exports = Pool;